package com.supreme.securityserver.controller;

import com.supreme.commonboot.exception.BizException;
import com.supreme.commonboot.utils.AjaxResp;
import com.supreme.commonentity.mysql.primary.SysUser;
import com.supreme.commonmybatis.service.quick.UserOrmService;
import com.supreme.securityserver.constants.SecurityConst;
import com.supreme.securityserver.entity.LoginUser;
import com.supreme.securityserver.security.AuthTokenService;
import com.supreme.securityserver.utils.TokenUtils;
import io.jsonwebtoken.Claims;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

@RestController
@RequestMapping(value = "test")
public class TestController {

    @Resource
    private AuthTokenService authTokenService;

    @Resource
    public RedisTemplate<String, LoginUser> redisTemplate;

    @Resource
    private HttpServletRequest httpServletRequest;

    @Resource
    private UserOrmService userOrmService;

    @GetMapping(value = "hello")
    public AjaxResp hello() {
        return AjaxResp.instance();
    }

    @GetMapping(value = "exception")
    public AjaxResp exception(@RequestParam(value = "message", required = false) String message) {
        try {
            Optional.ofNullable(message).orElseThrow((Supplier<Throwable>) () -> new BizException("exception"));
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        return AjaxResp.instance();
    }

    @GetMapping(value = "testHeader")
    public AjaxResp testHeader() {
        Enumeration<String> headerNames = httpServletRequest.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String name = headerNames.nextElement();
            System.out.println("name = " + name);
        }
        return AjaxResp.instance();
    }

    @PostMapping(value = "createToken/{subject}")
    public AjaxResp createToken(@PathVariable(value = "subject") String subject, @RequestBody Map<String, Object> claims) {
        String token = TokenUtils.createToken(subject, claims, SecurityConst.JWT_EXPIRATION);
        return AjaxResp.instance(token);
    }

    @GetMapping(value = "parseToken/{token}")
    public AjaxResp createToken(@PathVariable(value = "token") String token,
                                @RequestParam(value = "params", required = false) List<String> paramList) {
        Claims claims = TokenUtils.parseToken(token);
        if (Objects.nonNull(paramList)) {
            for (String s : paramList) {
                Object o = claims.get(s);
                System.out.printf("key: %s, value: %s\n", s, o);
            }
        }
        return AjaxResp.instance(claims);
    }

    @GetMapping(value = "cacheLoginUser/{userId}")
    public AjaxResp cacheLoginUser(@PathVariable(value = "userId") Long userId) {
        SysUser sysUser = userOrmService.getById(userId);
        LoginUser loginUser = new LoginUser(sysUser);
        loginUser.setLoginTime(System.currentTimeMillis());
        loginUser.setExpireTime(System.currentTimeMillis() + 3600 * 1000);

        ValueOperations<String, LoginUser> valueOperations = redisTemplate.opsForValue();
        valueOperations.set("LOGIN_USER_TEMP", loginUser, 10, TimeUnit.MINUTES);

        LoginUser getLoginUser = valueOperations.get("LOGIN_USER_TEMP");
        return AjaxResp.instance(getLoginUser);
    }
}
